/**
 * Iscas 85 Logic Gate Node.
 * This class represents a logic gate node in the circuit graph and is responsible
 * for calculating the node value.
 *
 */
public class Iscas85Logic extends Iscas85Node {

	/**
	 * Values of the entries
	 */
	public byte[] faninValues;
	/**
	 * True if the result is final (all entry nodes have a value)
	 */
	public int completed;

	/**
	 * Processes and propagates the node results
	 * 
	 * @return Result of the node processing
	 */
	@Override
	public byte processInput() {

		// Value previously computed
		if (value != -1)
			return value;
		
		switch (nodeType) {
		case AND:
			value = 1;
			for (int i = 0; i < faninValues.length; ++i) {
				value &= faninValues[i];
			}
			break;
		case NAND:
			value = 1;
			for (int i = 0; i < faninValues.length; ++i) {
				value &= faninValues[i];
			}
			value = (byte) (value == 1 ? 0 : 1);
			break;
		case OR:
			value = 0;
			for (int i = 0; i < faninValues.length; ++i) {
				value |= faninValues[i];
			}
			break;
		case NOR:
			value = 0;
			for (int i = 0; i < faninValues.length; ++i) {
				value |= faninValues[i];
			}
			value = (byte) (value == 1 ? 0 : 1);
			break;
		case XOR:
			value = 0;
			for (int i = 0; i < faninValues.length; ++i) {
				value ^= faninValues[i];
			}
			break;
		case NOT:
			value = (byte) (faninValues[0] == 1 ? 0 : 1);
			break;
		case XNOR:
			value = 0;
			for (int i = 0; i < faninValues.length; ++i) {
				value ^= faninValues[i];
			}
			value = (byte) (value == 1 ? 0 : 1);
			break;
		}

		return value;
	}

	/**
	 * Inserts the result of a previous node
	 * 
	 * @param value
	 *            Value to insert
	 */
	public void insertValue(byte value) {
		if (faninValues.length == completed)
			return;
		else {
			faninValues[completed++] = value;
		}
	}

	/**
	 * Checks if all the inputs are in
	 * 
	 * @return TRUE if inputs are complete, FALSE otherwise
	 */
	public boolean isComplete() {
		return completed == faninValues.length ;
	}

}
